package com.mce.nebula.service;

import com.mce.nebula.dto.*;
import com.mce.nebula.entity.Enterprise;
import com.mce.nebula.entity.Team;
import com.mce.nebula.entity.User;
import com.mce.nebula.repository.EnterpriseRepository;
import com.mce.nebula.repository.TeamRepository;
import com.mce.nebula.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 企业服务
 * 对应Python的enterprise_services
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class EnterpriseService {

    private final EnterpriseRepository enterpriseRepository;
    private final UserRepository userRepository;
    private final TeamRepository teamRepository;

    // 企业名正则表达式
    private static final Pattern ENTERPRISE_NAME_PATTERN = Pattern.compile("^[a-z0-9-]*$");

    // 默认企业ID文件路径
    private static final String DEFAULT_ENTERPRISE_ID_PATH = "/opt/rainbond/enterprise_id";

    /**
     * 获取第一个企业（默认企业）
     */
    public Optional<Enterprise> getEnterpriseFirst() {
        return enterpriseRepository.findAll().stream().findFirst();
    }

    /**
     * 分页查询所有企业
     * 对应Python的list_all方法
     */
    public PageResult<EnterpriseInfo> listAll(String query, int page, int pageSize) {
        Pageable pageable = PageRequest.of(page - 1, pageSize);
        Page<Enterprise> enterprisePage;

        if (query != null && !query.trim().isEmpty()) {
            // 这里应该实现按查询条件过滤，简化处理
            enterprisePage = enterpriseRepository.findAll(pageable);
        } else {
            enterprisePage = enterpriseRepository.findAll(pageable);
        }

        List<EnterpriseInfo> data = enterprisePage.getContent().stream()
                .map(this::convertToEnterpriseInfo)
                .collect(Collectors.toList());

        return new PageResult<>(data, enterprisePage.getTotalElements());
    }

    /**
     * 转换企业实体为企业信息DTO
     */
    private EnterpriseInfo convertToEnterpriseInfo(Enterprise enterprise) {
        EnterpriseInfo info = new EnterpriseInfo();
        info.setEnterpriseId(enterprise.getEnterpriseId());
        info.setEnterpriseName(enterprise.getEnterpriseName());
        info.setEnterpriseAlias(enterprise.getEnterpriseAlias());
        info.setCreateTime(enterprise.getCreateTime());
        info.setIsActive(enterprise.getIsActive());

        // 统计区域数量
        info.setRegionNum(0); // TODO: 实现区域统计

        // 统计用户数量
        long userCount = userRepository.countByEnterpriseId(enterprise.getEnterpriseId());
        info.setUserNum(userCount);

        // 统计团队数量
        long teamCount = teamRepository.countByEnterpriseId(enterprise.getEnterpriseId());
        info.setTeamNum(teamCount);

        return info;
    }

    /**
     * 更新企业信息
     * 对应Python的update方法
     */
    @Transactional
    public void update(String enterpriseId, Map<String, Object> data) {
        Enterprise enterprise = enterpriseRepository.findByEnterpriseId(enterpriseId)
                .orElseThrow(() -> new IllegalArgumentException("企业不存在"));

        if (data.containsKey("alias") && data.get("alias") != null) {
            String alias = data.get("alias").toString();
            if (!alias.trim().isEmpty()) {
                enterprise.setEnterpriseAlias(alias);
            }
        }

        if (data.containsKey("name") && data.get("name") != null) {
            String name = data.get("name").toString();
            if (!name.trim().isEmpty()) {
                enterprise.setEnterpriseName(name);
            }
        }

        enterpriseRepository.save(enterprise);
    }

    /**
     * 更新企业别名
     * 对应Python的update_alias方法
     */
    @Transactional
    public void updateAlias(String enterpriseId, String alias) {
        Enterprise enterprise = enterpriseRepository.findByEnterpriseId(enterpriseId)
                .orElseThrow(() -> new IllegalArgumentException("企业不存在"));

        enterprise.setEnterpriseAlias(alias);
        enterpriseRepository.save(enterprise);
    }

    /**
     * 创建企业
     * 对应Python的create_enterprise方法
     */
    @Transactional
    public Enterprise createEnterprise(String enterpriseName, String enterpriseAlias) {
        Enterprise enterprise = new Enterprise();

        // 处理企业英文名
        String finalEnterpriseName;
        if (enterpriseName != null && !enterpriseName.trim().isEmpty()) {
            if (!ENTERPRISE_NAME_PATTERN.matcher(enterpriseName).matches()) {
                log.error("Invalid enterprise name: {}", enterpriseName);
                throw new IllegalArgumentException("enterprise_name must consist of lower case alphanumeric characters or -");
            }

            if (enterpriseRepository.existsByEnterpriseName(enterpriseName)) {
                throw new IllegalArgumentException("enterprise_name [" + enterpriseName + "] already existed!");
            }
            finalEnterpriseName = enterpriseName;
        } else {
            finalEnterpriseName = randomEnterpriseName(10);
        }
        enterprise.setEnterpriseName(finalEnterpriseName);

        // 生成企业ID
        String enterpriseId = generateEnterpriseId(finalEnterpriseName);
        enterprise.setEnterpriseId(enterpriseId);

        // 处理企业别名
        if (enterpriseAlias == null || enterpriseAlias.trim().isEmpty()) {
            enterprise.setEnterpriseAlias("企业" + finalEnterpriseName);
        } else {
            enterprise.setEnterpriseAlias(enterpriseAlias);
        }

        enterprise.setIsActive(true);
        enterprise.setEnterpriseToken(UUID.randomUUID().toString().replace("-", ""));

        return enterpriseRepository.save(enterprise);
    }

    /**
     * 生成企业ID
     */
    private String generateEnterpriseId(String enterpriseName) {
        // 检查是否为第一个企业
        boolean isFirstEnterprise = enterpriseRepository.count() == 0;

        String enterpriseId = System.getenv("ENTERPRISE_ID");
        if (enterpriseId == null && isFirstEnterprise) {
            enterpriseId = UUID.randomUUID().toString().replace("-", "");

            // 尝试从文件读取企业ID
            try {
                if (Files.exists(Paths.get(DEFAULT_ENTERPRISE_ID_PATH))) {
                    enterpriseId = Files.readString(Paths.get(DEFAULT_ENTERPRISE_ID_PATH)).trim();
                }
            } catch (IOException e) {
                log.warn("Failed to read enterprise ID from file: {}", DEFAULT_ENTERPRISE_ID_PATH, e);
            }
        }

        return enterpriseId != null ? enterpriseId : UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 生成随机租户名
     * 对应Python的random_tenant_name方法
     */
    public String randomTenantName(String enterpriseId, int length) {
        String tenantName = generateRandomName(length);

        // 检查租户名是否已存在
        while (teamRepository.existsByTenantName(tenantName)) {
            tenantName = generateRandomName(length);
        }

        return tenantName;
    }

    /**
     * 生成随机企业名
     * 对应Python的random_enterprise_name方法
     */
    public String randomEnterpriseName(int length) {
        String enterpriseName = generateRandomName(length);

        // 检查企业名是否已存在
        while (enterpriseRepository.existsByEnterpriseName(enterpriseName)) {
            enterpriseName = generateRandomName(length);
        }

        return enterpriseName;
    }

    /**
     * 生成随机名称（小写字母和数字）
     */
    private String generateRandomName(int length) {
        String chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuilder sb = new StringBuilder(length);

        for (int i = 0; i < length; i++) {
            sb.append(chars.charAt(random.nextInt(chars.length())));
        }

        return sb.toString();
    }

    /**
     * 创建OAuth企业
     * 对应Python的create_oauth_enterprise方法
     */
    @Transactional
    public Enterprise createOauthEnterprise(String enterpriseName, String enterpriseAlias, String enterpriseId) {
        Enterprise enterprise = new Enterprise();
        enterprise.setEnterpriseName(enterpriseName);
        enterprise.setEnterpriseId(enterpriseId);
        enterprise.setEnterpriseAlias(enterpriseAlias);
        enterprise.setIsActive(true);
        enterprise.setEnterpriseToken(UUID.randomUUID().toString().replace("-", ""));

        return enterpriseRepository.save(enterprise);
    }

    /**
     * 激活企业
     * 对应Python的active方法
     */
    @Transactional
    public boolean active(Enterprise enterprise, String enterpriseToken) {
        enterprise.setEnterpriseToken(enterpriseToken);
        enterprise.setIsActive(true);
        enterpriseRepository.save(enterprise);
        return true;
    }

    /**
     * 设置用户为企业管理员
     */
    @Transactional
    public void makeUserAsAdminForEnterprise(Long userId, String enterpriseId) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new IllegalArgumentException("用户不存在"));

        user.setEnterpriseId(enterpriseId);
        user.setSysAdmin(true);
        userRepository.save(user);

        log.info("设置用户 {} 为企业 {} 的管理员", user.getNickName(), enterpriseId);
    }

    /**
     * 根据企业ID查找企业
     */
    public Optional<Enterprise> findByEnterpriseId(String enterpriseId) {
        return enterpriseRepository.findByEnterpriseId(enterpriseId);
    }

    /**
     * 根据企业别名查找企业
     */
    public Optional<Enterprise> findByEnterpriseAlias(String enterpriseAlias) {
        return enterpriseRepository.findByEnterpriseAlias(enterpriseAlias);
    }

    /**
     * 检查企业别名是否存在
     */
    public boolean existsByEnterpriseAlias(String enterpriseAlias) {
        return enterpriseRepository.existsByEnterpriseAlias(enterpriseAlias);
    }

    /**
     * 检查企业ID是否存在
     */
    public boolean existsByEnterpriseId(String enterpriseId) {
        return enterpriseRepository.existsByEnterpriseId(enterpriseId);
    }

    /**
     * 根据企业ID获取企业
     * 对应Python的get_enterprise_by_id方法
     */
    public Optional<Enterprise> getEnterpriseById(String enterpriseId) {
        return enterpriseRepository.findByEnterpriseId(enterpriseId);
    }

    /**
     * 根据企业名获取企业
     * 对应Python的get_enterprise_by_enterprise_name方法
     */
    public Optional<Enterprise> getEnterpriseByEnterpriseName(String enterpriseName, boolean throwException) {
        Optional<Enterprise> enterprise = enterpriseRepository.findByEnterpriseName(enterpriseName);
        if (throwException && enterprise.isEmpty()) {
            throw new IllegalArgumentException("企业不存在: " + enterpriseName);
        }
        return enterprise;
    }

    /**
     * 根据企业ID获取企业
     * 对应Python的get_enterprise_by_enterprise_id方法
     */
    public Optional<Enterprise> getEnterpriseByEnterpriseId(String enterpriseId, boolean throwException) {
        Optional<Enterprise> enterprise = enterpriseRepository.findByEnterpriseId(enterpriseId);
        if (throwException && enterprise.isEmpty()) {
            throw new IllegalArgumentException("企业不存在: " + enterpriseId);
        }
        return enterprise;
    }

    /**
     * 根据企业ID列表获取企业列表
     * 对应Python的get_enterprise_by_eids方法
     */
    public List<Enterprise> getEnterprisesByEnterpriseIds(List<String> enterpriseIds) {
        return enterpriseRepository.findByEnterpriseIdIn(enterpriseIds);
    }

    /**
     * 创建租户企业
     * 对应Python的create_tenant_enterprise方法
     */
    @Transactional
    public Enterprise createTenantEnterprise(String enterpriseId, String enterpriseName,
                                             String enterpriseAlias, boolean isActive) {
        Enterprise enterprise = new Enterprise();
        enterprise.setEnterpriseId(enterpriseId);
        enterprise.setEnterpriseName(enterpriseName);
        enterprise.setEnterpriseAlias(enterpriseAlias);
        enterprise.setIsActive(isActive);
        enterprise.setEnterpriseToken(UUID.randomUUID().toString().replace("-", ""));

        return enterpriseRepository.save(enterprise);
    }

    /**
     * 获取企业应用市场信息列表
     * 对应Python的list_appstore_infos方法
     */
    public PageResult<AppStoreInfo> listAppstoreInfos(String query, int page, int pageSize) {
        // 这里应该实现应用市场信息查询
        // 简化处理，返回空列表
        List<AppStoreInfo> infos = new ArrayList<>();

        // 模拟应用市场信息
        AppStoreInfo info = new AppStoreInfo();
        info.setAccessUrl("https://api.goodrain.com");
        info.setAppstoreName("好雨科技公有应用市场(默认)");
        infos.add(info);

        return new PageResult<>(infos, infos.size());
    }

    /**
     * 更新应用市场信息
     * 对应Python的update_appstore_info方法
     */
    @Transactional
    public Enterprise updateAppstoreInfo(String enterpriseId, Map<String, Object> data) {
        Enterprise enterprise = enterpriseRepository.findByEnterpriseId(enterpriseId)
                .orElseThrow(() -> new IllegalArgumentException("企业不存在"));

        String accessUrl = data.get("access_url").toString();

        // 这里应该更新企业Token信息
        // 简化处理
        enterprise.setEnterpriseToken(UUID.randomUUID().toString().replace("-", ""));
        enterprise = enterpriseRepository.save(enterprise);

        // 设置应用市场名称
        String appstoreName = "";
        if (accessUrl.contains("api.goodrain.com")) {
            appstoreName = "好雨科技公有应用市场(默认)";
        }

        return enterprise;
    }

    /**
     * 获取企业运行服务统计
     * 对应Python的get_enterprise_runing_service方法
     */
    public EnterpriseRunningServiceStats getEnterpriseRunningService(String enterpriseId, List<Object> regions) {
        // 这里应该实现企业运行服务统计
        // 简化处理，返回模拟数据
        EnterpriseRunningServiceStats stats = new EnterpriseRunningServiceStats();

        ServiceGroupStats serviceGroupStats = new ServiceGroupStats();
        serviceGroupStats.setTotal(0);
        serviceGroupStats.setRunning(0);
        serviceGroupStats.setClosed(0);
        stats.setServiceGroups(serviceGroupStats);

        ComponentStats componentStats = new ComponentStats();
        componentStats.setTotal(0);
        componentStats.setRunning(0);
        componentStats.setClosed(0);
        stats.setComponents(componentStats);

        return stats;
    }

    /**
     * 获取企业告警信息
     * 对应Python的get_enterprise_alerts方法
     */
    public List<AlertInfo> getEnterpriseAlerts(String enterpriseId) {
        // 这里应该实现企业告警查询
        // 简化处理，返回空列表
        return new ArrayList<>();
    }

    /**
     * 获取Rainbond组件信息
     * 对应Python的get_rbdcomponents方法
     */
    public List<ComponentInfo> getRbdComponents(String regionName) {
        // 这里应该实现Rainbond组件查询
        // 简化处理，返回空列表
        return new ArrayList<>();
    }

    /**
     * 获取节点详情
     * 对应Python的get_node_detail方法
     */
    public NodeDetail getNodeDetail(String regionName, String nodeName) {
        // 这里应该实现节点详情查询
        // 简化处理，返回模拟数据
        NodeDetail nodeDetail = new NodeDetail();
        nodeDetail.setName(nodeName);
        nodeDetail.setStatus("Ready");
        nodeDetail.setIp("127.0.0.1");
        return nodeDetail;
    }

    /**
     * 获取节点列表
     * 对应Python的get_nodes方法
     */
    public NodeListResult getNodes(String regionName) {
        // 这里应该实现节点列表查询
        // 简化处理，返回模拟数据
        List<NodeInfo> nodes = new ArrayList<>();
        Map<String, Integer> clusterRoleCount = new HashMap<>();

        return new NodeListResult(nodes, clusterRoleCount);
    }

    /**
     * 创建用户角色
     * 对应Python的create_user_roles方法
     */
    @Transactional
    public List<Object> createUserRoles(String enterpriseId, Long userId, String tenantName, List<Long> roleIds) {
        // 这里应该实现用户角色创建
        // 简化处理，返回空列表
        return new ArrayList<>();
    }

    /**
     * 获取企业菜单
     * 对应Python的get_enterprise_menus方法
     */
    public List<MenuInfo> getEnterpriseMenus(String enterpriseId) {
        // 这里应该实现企业菜单查询
        // 简化处理，返回空列表
        return new ArrayList<>();
    }

    /**
     * 添加企业菜单
     * 对应Python的add_enterprise_menu方法
     */
    @Transactional
    public void addEnterpriseMenu(Map<String, Object> data) {
        // 这里应该实现企业菜单添加
        log.info("Adding enterprise menu: {}", data);
    }

    /**
     * 根据父ID获取菜单
     * 对应Python的get_menus_by_parent_id方法
     */
    public List<MenuInfo> getMenusByParentId(String enterpriseId, Long parentId) {
        // 这里应该实现根据父ID查询菜单
        // 简化处理，返回空列表
        return new ArrayList<>();
    }

    /**
     * 更新企业菜单
     * 对应Python的update_enterprise_menu方法
     */
    @Transactional
    public void updateEnterpriseMenu(String enterpriseId, Long id, Map<String, Object> data) {
        // 这里应该实现企业菜单更新
        log.info("Updating enterprise menu {} for enterprise {}: {}", id, enterpriseId, data);
    }

    /**
     * 删除企业菜单
     * 对应Python的delete_enterprise_menu方法
     */
    @Transactional
    public void deleteEnterpriseMenu(String enterpriseId, Long id) {
        // 这里应该实现企业菜单删除
        log.info("Deleting enterprise menu {} for enterprise {}", id, enterpriseId);
    }

    public List<Enterprise> getAll() {
        return this.enterpriseRepository.findAll();
    }
}